package com.tech4u.edu4u_demo;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Adapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.iflytek.cloud.InitListener;
import com.iflytek.cloud.RecognizerListener;
import com.iflytek.cloud.RecognizerResult;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechRecognizer;
import com.iflytek.cloud.SpeechSynthesizer;
import com.iflytek.cloud.SynthesizerListener;
import com.quyuanfactory.xvaide.XVAide;
import com.tech4u.edu4u_demo.adapter.MyAdapter;
import com.tech4u.edu4u_demo.entity.ChatDetail;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    /**
     * 窗口浮动 request code
     */
    private static final int REQ_CODE_OVERLAY = 1000;

    private static final String TAG = "模型>>>";


    Context mContext;

    boolean CURRENT_INPUT_TYPE_WORD = false;


    TextView tv_input_type, tv_speak;
    EditText et_word;
    Button btn_send;
    LinearLayout ll_content_word;
    RecyclerView recyclerView;
    IatDialog iatDialog = new IatDialog();


    // 语音听写对象
    private SpeechRecognizer mIat;
    // 语音合成对象
    private SpeechSynthesizer mTts;
    // 适配器
    MyAdapter myAdapter;
    List<ChatDetail> list = new ArrayList<>();


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mContext = this;

        permissionsApply();
    }

    /**
     * 申请权限权限
     */
    public void permissionsApply() {
        /** 窗口浮动权限 */
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { // 7.0 以上需要引导用去设置开启窗口浮动权限
            if (!Settings.canDrawOverlays(mContext)) {
                Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + this.getPackageName()));
                startActivityForResult(intent, REQ_CODE_OVERLAY);
            } else {
                initAll();
            }
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // 6.0 动态申请窗口浮动权限
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.SYSTEM_ALERT_WINDOW}, REQ_CODE_OVERLAY);
        }
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.LOCATION_HARDWARE,Manifest.permission.READ_PHONE_STATE,
                Manifest.permission.WRITE_SETTINGS,Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.RECORD_AUDIO,Manifest.permission.READ_CONTACTS}, 11);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            if (requestCode == REQ_CODE_OVERLAY) {
                initAll();
            }
        }
    }


    /**
     * 初始化
     */
    public void initAll() {
        tv_input_type = findViewById(R.id.tv_input_type);
        tv_speak = findViewById(R.id.tv_speak);
        et_word = findViewById(R.id.et_word);
        ll_content_word = findViewById(R.id.ll_content_word);
        btn_send = findViewById(R.id.btn_send);
        recyclerView = findViewById(R.id.recycler_view);

        tv_input_type.setOnClickListener(this);
        btn_send.setOnClickListener(this);


        myAdapter = new MyAdapter(list, mContext);
        recyclerView.setAdapter(myAdapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(mContext));


        tv_speak.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {

                switch (motionEvent.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        //开始录音
                        tv_speak.setBackgroundColor(getResources().getColor(R.color.grey));
                        tv_speak.setText("录音中.....");
                        iatDialog.show(getSupportFragmentManager(), "as");
                        int ret = mIat.startListening(mRecognizerListener);
                        break;
                    case MotionEvent.ACTION_UP:
                        tv_speak.setBackgroundColor(getResources().getColor(R.color.white));
                        tv_speak.setText("按住讲话");
                        iatDialog.dismiss();
                        mIat.stopListening();
                        break;
                    default:

                }


                return true;
            }
        });

        startXVAide();

        //语音识别(语音->文字)
        mIat = SpeechRecognizer.createRecognizer(MainActivity.this, mTtsInitListener);
        //语音合成(文字->语音)
        mTts = SpeechSynthesizer.createSynthesizer(MainActivity.this, mTtsInitListener);
    }


    InitListener mTtsInitListener = new InitListener() {
        @Override
        public void onInit(int i) {

        }
    };

    /**
     * 听写监听器。
     */
    private RecognizerListener mRecognizerListener = new RecognizerListener() {

        @Override
        public void onBeginOfSpeech() {
            // 此回调表示：sdk内部录音机已经准备好了，用户可以开始语音输入
        }

        @Override
        public void onError(SpeechError error) {
            // Tips：
            // 错误码：10118(您没有说话)，可能是录音机权限被禁，需要提示用户打开应用的录音权限。


        }

        @Override
        public void onEndOfSpeech() {
            // 此回调表示：检测到了语音的尾端点，已经进入识别过程，不再接受语音输入
        }

        @Override
        public void onResult(RecognizerResult results, boolean isLast) {
            String str = SpeechUtils.printResult(results);
            ChatDetail chatDetail = new ChatDetail();
            chatDetail.setType(2);
            chatDetail.setWord(str);
            chatDetail.setSortOrder(false);
            addChatQuestion(chatDetail);
        }

        @Override
        public void onVolumeChanged(int volume, byte[] data) {
            Log.d(TAG, "返回音频数据：" + volume);
            iatDialog.updateProgress(volume * 2);
        }

        @Override
        public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {

        }
    };

    /**
     * 合成回调监听。
     */
    private SynthesizerListener mTtsListener = new SynthesizerListener() {
        @Override
        public void onSpeakBegin() {

        }

        @Override
        public void onBufferProgress(int i, int i1, int i2, String s) {

        }

        @Override
        public void onSpeakPaused() {

        }

        @Override
        public void onSpeakResumed() {

        }

        @Override
        public void onSpeakProgress(int i, int i1, int i2) {

        }

        @Override
        public void onCompleted(SpeechError speechError) {

        }

        @Override
        public void onEvent(int i, int i1, int i2, Bundle bundle) {

        }
    };

    public void startXVAide() {

        XVAide.Init(this, new XVAide.CallBack() {
            @Override
            public void aideLoaded(boolean ret) {
                Log.d(TAG, "aideLoaded: " + ret);
                float[] rect = new float[]{0f, 0.2f, 0.5f, 0.5f};
                XVAide.ShowModelRect(rect);
                XVAide.ShowModel();

                Rect frame = new Rect();
                getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
                float w = frame.width();
                float h = frame.height();

                float[] rt = XVAide.ModelRect();
            }

            @Override
            public void aideClicked(String name) {
                //{"Idle","Nod","SayNo","Happy","Unhappy","Walk","Run","Great","Rest","TurnAround","Think","SayHello","Point","LookUp","Bow"};
                Log.d(TAG, "aideClicked: " + name);
                if (name.equals("Tou")) {
                    XVAide.StopAnimatePose("Manual", "Tou"); //stop pose animation, reset, not necessary!, for demo
                    XVAide.Animate("Nod", 20.0f);
                } else if (name.equals("qunzi")) {
                    XVAide.Animate("Great", 20.0f);
                } else if (name.equals("Leg")) {
                    XVAide.Animate("Walk", 20.0f);
                }
            }

            @Override
            public void aideDoubleClicked(String s) {

            }

            @Override
            public void animateFinished(String s) {

            }
        });
    }


    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.tv_input_type:
                /** 输入方式切换 */
                if (CURRENT_INPUT_TYPE_WORD) {
                    tv_input_type.setText("讲话");
                    tv_speak.setVisibility(View.VISIBLE);
                    ll_content_word.setVisibility(View.INVISIBLE);
                } else {
                    tv_input_type.setText("文字");
                    tv_speak.setVisibility(View.INVISIBLE);
                    ll_content_word.setVisibility(View.VISIBLE);
                }
                CURRENT_INPUT_TYPE_WORD = !CURRENT_INPUT_TYPE_WORD;
                break;
            case R.id.btn_send:
                if (TextUtils.isEmpty(et_word.getText().toString().trim())) {
                    return;
                }
                String word = et_word.getText().toString().trim();
                ChatDetail chatDetail = new ChatDetail();
                chatDetail.setSortOrder(false);
                chatDetail.setType(1);
                chatDetail.setWord(word);
                addChatQuestion(chatDetail);
                et_word.setText("");
                break;

        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        XVAide.Destroy();
    }


    /**
     * 添加一条聊天消息
     *
     * @param chatDetail
     */
    public void addChatAnswer(ChatDetail chatDetail) {
        list.add(chatDetail);
        myAdapter.notifyDataSetChanged();
        recyclerView.scrollToPosition(list.size() - 1);
    }

    public void addChatQuestion(ChatDetail chatDetail) {
        addChatAnswer(chatDetail);
        httpRequest(chatDetail.getWord());
    }


    /**
     * 图灵请求
     *
     * @param str
     */
    public void httpRequest(String str) {
        JSONObject params = new JSONObject();
        try {
            params.put("reqType", 0);
            params.put("userInfo", new JSONObject().put("apiKey", "d72fe439ce1140c49875ec9e3059780d").put("userId", "guohao"));
            params.put("perception", new JSONObject().put("inputText", new JSONObject().put("text", str)));

            JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, "http://openapi.tuling123.com/openapi/api/v2", params, new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                    Log.e("dime volley success", String.valueOf(response));
                    try {
                        JSONArray array = response.getJSONArray("results");
                        for (int i = 0; i < array.length(); i++) {

                            if (array.getJSONObject(i).getString("resultType").equals("text")) {
                                String resStr = array.getJSONObject(i).getJSONObject("values").getString("text");
                                mTts.startSpeaking(resStr, mTtsListener);
                                ChatDetail chatDetail = new ChatDetail();
                                chatDetail.setWord(resStr);
                                chatDetail.setType(1);
                                chatDetail.setSortOrder(true);
                                addChatAnswer(chatDetail);
                                break;
                            }
                        }

                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Log.e("dime volley error", String.valueOf(error));
                }
            });
            MyApp.mQueue.add(jsonObjectRequest);
        } catch (JSONException e) {
            e.printStackTrace();
            Log.e("dime volley exception", e.getMessage());
        }

    }
}
